package com.capgemini.task;

/**
 * @description 作业要求：
 * - README文件编写 tasking列表，满足Given When Then句式
 * - 将tasking逐个翻译为测试代码，满足Should When Then句式
 * - 小步提交代码，每完成一件事情就提交一次代码
 * - 尽可能使用快捷键，至少知道常用快捷键，课堂随机提问：提取变量、提取方法、重命名、执行测试、切换编辑文件、创建新文件、上下阔选
 * @version 1.0.0
 * @author haiyuan.jiao
 * @since 2022/2/11
 **/
public class FizzBuzzWhizz {

    private static String FIZZ = "Fizz";
    private static String BUZZ = "Buzz";
    private static String WHIZZ = "Whizz";

    public String numberOff(Integer num) {
        StringBuilder sb = new StringBuilder();
        Boolean flag_7_3 = true; //用于忽略规则6中忽略被3整除的判定
        Boolean flag_3 = true; //用于忽略被3整除的判定
        Boolean flag_5 = true; //用于忽略被5整除的判定
        //7. 如果数字中包含了7，则忽略被5整除的判定，若同时还包含5，就忽略规则6中忽略被3整除的判定，比如要报75的同学只报Fizz，其他case自己补齐。
        if (isContains(num, "7")) {
            flag_5 = false;
            if (isContains(num, "5")) {
                flag_7_3 = false;
            }
        }
        //6. 如果数字中包含了5，那么忽略规则4和规则5，并且忽略被3整除的判定，比如要报35的同学不报Fizz，报BuzzWhizz，其他case自己补齐。
        if (!isContains(num, "5")) {
            //4. 学生报数时，如果所报数字包含了3，那么也不能说该数字，而是要说相应的单词，比如要 报13的同学应该说Fizz。
            //5. 如果数字中包含了3，那么忽略规则2和规则3，比如要报30的同学只报Fizz，不报FizzBuzz。
            if (isContains(num, "3")) {
                return FIZZ;
            }
        } else {
            if (flag_7_3) {
                flag_3 = false;
            }
        }
        //2. 学生报数时，如果所报数字是3的倍数，那么不能说该数字，而要说Fizz;如果所报数字是5 的倍数，那么要说Buzz;如果所报数字是第7的倍数，那么要说Whizz。
        //3. 学生报数时，如果所报数字同时是两个特殊数的倍数情况下，也要特殊处理，比如3和5的 倍数，那么不能说该数字，而是要说FizzBuzz, 以此类推。如果同时是三个特殊数的倍数， 那么要说FizzBuzzWhizz。
        if (flag_3) {
            if (isTrue(num, 3)) {
                sb.append(FIZZ);
            }
        }
        if (flag_5) {
            if (isTrue(num, 5)) {
                sb.append(BUZZ);
            }
        }
        if (isTrue(num, 7)) {
            sb.append(WHIZZ);
        }
        //1. 让所有学生排成一队，然后按顺序报数。
        return sb.toString().equals("") ? String.valueOf(num) : sb.toString();
    }

    private boolean isTrue(Integer num, Integer n) {
        return num % n == 0;
    }

    private boolean isContains(Integer num, String s) {
        return String.valueOf(num).contains(s);
    }

}
